/*-------------------------------------------------------------------------
| :
| ------------
| 
---------------------------------------------------------------------------*/
template<long Min, long Max, class T>
class TCustomType : public TObject
{
private:
	T value;
public:
	static const long MaxValue = Max;
	static const long MinValue = Min;
	enum Type{ TypeBool, TypeInt, TypeFloat };
	typedef TCustomType<Min, Max, T> Reference;

	TCustomType(T val) : TObject(), value(val) {}
	inline Type GenType(const bool&)					{ return TypeBool; }
	inline Type GenType(const int&)						{ return TypeInt; }
	inline Type GenType(const float&)					{ return TypeFloat; }
	inline Type GetType(void)							{ return GenType(value); }
	template<class TCast>
	inline TCast To(void)								{ return static_cast<TCast>(value); }
};


enum BoolValue{ False = 0, True = 1 };

class TBool : public TObject
{
private:
    BoolValue value;
public:
    TBool(BoolValue val): value(val)
    {
    }
};

class Bool : public ref<TBool>
{
public:
    typedef ref<TBool> Base;
    Bool(): Base(new TBool(False))
    {
    }
    Bool(BoolValue val): Base(new TBool(val))
    {
    }

    Bool(Base copy) : Base(copy) {} // for Cast
};

template<long Min, long Max, class T>
class CustomType : public ref<TCustomType<Min, Max, T> >
{
public:
        typedef ref<TCustomType<Min, Max, T> > Base;

	typedef T ValueType;
        CustomType() : Base(new TCustomType<Min, Max, T>(0)) {}
        CustomType(T val) : Base(new TCustomType<Min, Max, T>(val)) {}
        CustomType(ref<TCustomType<Min, Max, T> > copy) : Base(copy) {} // for Cast
	inline CustomType & operator +=(CustomType val)	{ this->value += val.value;	return *this; }
	inline CustomType & operator -=(CustomType val)	{ this->value -= val.value; return *this; }
	inline CustomType & operator *=(CustomType val)	{ this->value *= val.value; return *this; }
	inline CustomType & operator /=(CustomType val)	{ this->value /= val.value; return *this; }

	inline CustomType & operator +=(T val)	{ this->value += val.value;	return *this; }
	inline CustomType & operator -=(T val)	{ this->value -= val.value; return *this; }
	inline CustomType & operator *=(T val)	{ this->value *= val.value; return *this; }
	inline CustomType & operator /=(T val)	{ this->value /= val.value; return *this; }

	inline CustomType & operator ++()				{ ++(this->value); return *this; }
	inline CustomType & operator --()				{ --(this->value); return *this; }

	inline Bool operator != (CustomType val)	{ return *this; }
	inline Bool operator != (T val)	{ return *this; }
	inline Bool operator == (CustomType val)	{ return *this; }
	inline Bool operator == (T val)	{ return *this; }
	inline Bool operator > (CustomType val)	{ return *this; }
	inline Bool operator > (T val)	{ return *this; }
	inline Bool operator < (CustomType val)	{ return *this; }
	inline Bool operator < (T val)	{ return *this; }
	template<class TCast>
	inline TCast To(void)			
	{ 
                return Base::mReference->To<TCast>();
	}
};

template<long Min, long Max, class T>
inline CustomType<Min, Max, T> operator + (CustomType<Min, Max, T> a, CustomType<Min, Max, T> b)
{ 
	return a += b;
}

template<long Min, long Max, class T>
inline CustomType<Min, Max, T> operator - (CustomType<Min, Max, T> a, CustomType<Min, Max, T> b)
{ 
	return a -= b;
}

template<long Min, long Max, class T>
inline CustomType<Min, Max, T> operator * (CustomType<Min, Max, T> a, CustomType<Min, Max, T> b)
{ 
	return a *= b;
}

template<long Min, long Max, class T>
inline CustomType<Min, Max, T> operator / (CustomType<Min, Max, T> a, CustomType<Min, Max, T> b)
{ 
	return a /= b;
}

typedef CustomType<0, 255, char> Char;

typedef CustomType<-35000, 35000, short> Int16;
typedef CustomType<0, 65000, unsigned short> UInt16;

typedef CustomType<-144444, 1444444, int> Int32;
typedef CustomType<0, 1444444, unsigned int> UInt32;


typedef TObject THandle;
typedef Object Handle;

//
template<class T>
class THandleBind : public THandle
{
protected:
	T mHandle;
public:
	THandleBind(T handle) : mHandle(handle)
	{}
};

//
class THandlePtr : public THandle
{
public:
	THandlePtr(void) : THandle()
	{}
	
	virtual UnSafeConstPtr GetPointer(void) const = 0;
};

typedef ref<THandlePtr> HandlePtr;

//
template<class T>
class THandleBindPtr : public THandlePtr
{
protected:
	T mHandle;
public:
	explicit THandleBindPtr(T handle) : mHandle(handle)
	{}
	
	virtual UnSafeConstPtr GetPointer(void) const
	{
		return static_cast<T>(mHandle);
	}
};
